home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / iconv8_s.arc / ICONT.ARC / TMAIN.C < prev    next >
C/C++ Source or Header  |  1990-03-28  |  13KB  |  528 lines

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "..\h\config.h"
  6. #include "general.h"
  7. #include "tproto.h"
  8. #include "..\h\paths.h"
  9.  
  10. /*
  11.  * Prototypes.
  12.  */
  13.  
  14. hidden    novalue    execute    Params((char *ofile,char *efile,char * *args));
  15. hidden    novalue    report Params((char *s));
  16. hidden    novalue    rmfiles Params((char **p));
  17. hidden    novalue    usage Params((noargs));
  18.  
  19. /*
  20.  * The following code is operating-system dependent [@tmain.01].  Include
  21.  *  files and such.
  22.  */
  23.  
  24. #if PORT
  25. Deliberate syntax error
  26. #endif                    /* PORT */
  27.  
  28. #if AMIGA || HIGHC_386 || MSDOS || MVS || UNIX || VM || VMS
  29. /* nothing is needed */
  30. #endif                    /* AMIGA || HIGHC_386 || ... */
  31.  
  32. #if ATARI_ST
  33. char *patharg;
  34. #endif                    /* ATARI_ST */
  35.  
  36. #if MACINTOSH
  37. #if MPW
  38. #include <fcntl.h>    \* MPW3 - for unlink() *\
  39. #include <CursorCtl.h>
  40. void SortOptions();
  41. #endif                    /* MPW */
  42. #endif                    /* MACINTOSH */
  43.  
  44. #if OS2
  45. #include <process.h>
  46. #endif                    /* OS2 */
  47. /*
  48.  * End of operating-system specific code.
  49.  */
  50.  
  51. #if IntBits == 16
  52. #ifdef strlen
  53. #undef strlen                /* pre-defined in some contexts */
  54. #endif                    /* strlen */
  55. #endif                    /* Intbits == 16 */
  56.  
  57. #ifndef Iconx
  58. #define Iconx IconxPath
  59. #endif                    /* Iconx */
  60.  
  61. /*
  62.  *  Define global variables.
  63.  */
  64.  
  65. #define Global
  66. #define Init(v) = v
  67. #include "globals.h"
  68.  
  69. char *ofile = NULL;            /* linker output file name */
  70.  
  71. /*
  72.  * getopt() variables
  73.  */
  74. extern int optind;        /* index into parent argv vector */
  75. extern int optopt;        /* character checked for validity */
  76. extern char *optarg;        /* argument associated with option */
  77.  
  78. /*
  79.  *  main program
  80.  */
  81. novalue main(argc,argv)
  82. int argc;
  83. char **argv;
  84.    {
  85.    int nolink = 0;            /* suppress linking? */
  86.    int errors = 0;            /* translator and linker errors */
  87.    char **tfiles, **tptr;        /* list of files to translate */
  88.    char **lfiles, **lptr;        /* list of files to link */
  89.    char **rfiles, **rptr;        /* list of files to remove */
  90.    char *efile = NULL;            /* stderr file */
  91.    char buf[MaxFileName];        /* file name construction buffer */
  92.    int c, n;
  93.    struct fileparts *fp;
  94.  
  95. #if MACINTOSH
  96. #if MPW
  97.    InitCursorCtl(NULL);
  98.    SortOptions(argv);
  99. #endif                    /* MPW */
  100. #endif                    /* MACINTOSH */
  101.  
  102.    /*
  103.     * Process options.
  104.     */
  105.    while ((c = getopt(argc,argv,Options)) != EOF)
  106.       switch (c) {
  107.          case 'c':            /* -c: compile only (no linking) */
  108.             nolink = 1;
  109.             break;
  110.          case 'e':            /* -e file: redirect stderr */
  111.             efile = optarg;
  112.             break;
  113.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  114.             m4pre = 1;
  115.             break;
  116.          case 'o':            /* -o file: name output file */
  117.             ofile = optarg;
  118.             break;
  119.  
  120. #if ATARI_ST
  121.          case 'p':            /* -p path: iconx path [ATARI] */
  122.             patharg = optarg;
  123.             break;
  124. #endif                    /* ATARI_ST */
  125.  
  126.          case 's':            /* -s: suppress informative messages */
  127.             silent = 1;
  128.             break;
  129.          case 'u':            /* -u: warn about undeclared ids */
  130.             uwarn = 1;
  131.             break;
  132.          case 't':            /* -t: turn on procedure tracing */
  133.             trace = -1;
  134.             break;
  135.  
  136.  
  137.          case 'L':            /* -L: enable linker debugging */
  138.  
  139. #ifdef DeBugLinker
  140.             Dflag = 1;
  141. #endif                    /* DeBugLinker */
  142.  
  143.             break;
  144.  
  145.          case 'S':            /* -Sxnnnn: set a size */
  146.             sizearg(optarg,argv);
  147.             break;
  148.          default:
  149.          case 'x':            /* -x illegal until after file list */
  150.             usage();
  151.          }
  152.  
  153.    /*
  154.     * Allocate space for lists of file names.
  155.     */
  156.    n = argc - optind + 1;
  157.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  158.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  159.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  160.  
  161.    /*
  162.     * Scan file name arguments.
  163.     */
  164.    while (optind < argc)  {
  165.       if (strcmp(argv[optind],"-x") == 0)    /* stop at -x */
  166.          break;
  167.       else if (strcmp(argv[optind],"-") == 0) {
  168.          *tptr++ = "-";                /* "-" means standard input */
  169.          *lptr++ = *rptr++ = "stdin.u1";
  170.          *rptr++ = "stdin.u2";
  171.          }
  172.       else {
  173.          fp = fparse(argv[optind]);        /* parse file name */
  174.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  175.             makename(buf,SourceDir,argv[optind], SourceSuffix);
  176.             *tptr++ = salloc(buf);        /* translate the .icn file */
  177.             makename(buf,TargetDir,argv[optind],U1Suffix);
  178.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  179.             makename(buf,TargetDir,argv[optind],U2Suffix);
  180.             *rptr++ = salloc(buf);        /* also remove .u2 */
  181.             }
  182.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  183.                || smatch(fp->ext,USuffix)) {
  184.             makename(buf,TargetDir,argv[optind],U1Suffix);
  185.             *lptr++ = salloc(buf);
  186.             }
  187.          else
  188.             quitf("bad argument %s",argv[optind]);
  189.          }
  190.       optind++;
  191.       }
  192.  
  193.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  194.    if (lptr == lfiles)
  195.       usage();                /* error -- no files named */
  196.  
  197.    /*
  198.     * Round hash table sizes to next power of two, and set masks for hashing.
  199.     */
  200.    chsize = round2(chsize);  cmask = chsize - 1;
  201.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  202.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  203.    ihsize = round2(ihsize);  imask = ihsize - 1;
  204.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  205.  
  206.    /*
  207.     * Translate .icn files to make .u1 and .u2 files.
  208.     */
  209.    if (tptr > tfiles) {
  210.       if (!silent)
  211.          report("Translating");
  212.       errors = trans(tfiles);
  213.       if (errors > 0)            /* exit if errors seen */
  214.          exit(ErrorExit);
  215.       }
  216.  
  217.    /*
  218.     * Link .u1 and .u2 files to make an executable.
  219.     */
  220.    if (nolink)                /* exit if no linking wanted */
  221.  
  222. #if MACINTOSH
  223. #if MPW
  224.       /*
  225.        *  Set type of translator output ucode (.u) files
  226.        *  to 'TEXT', so they can be easily viewed by editors.
  227.        */
  228.       {
  229.       char **p;
  230.       void setfile();
  231.       for (p = rfiles; *p; ++p)
  232.          setfile(*p,'TEXT','icon');
  233.       }
  234. #endif                    /* MPW */
  235. #endif                    /* MACINTOSH */
  236.  
  237.       exit(NormalExit);
  238.  
  239.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  240.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  241.    } else {                /* add extension in necessary */
  242.       fp = fparse(ofile);
  243.  
  244. #if !(MACINTOSH && MPW) /* This code provokes code generation bug in */
  245.         /* pre-release MPW 3.0 C compiler */
  246.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given, but wanted */
  247.          ofile = salloc(makename(buf,TargetDir,ofile,IcodeSuffix));
  248. #endif                    /* !(MACINTOSH && MPW) */
  249.  
  250.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  251.          ofile = salloc(makename(buf,TargetDir,ofile,IcodeSuffix));
  252.    }
  253.  
  254.    if (!silent)
  255.       report("Linking");
  256.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  257.  
  258.    /*
  259.     * Finish by removing intermediate files.
  260.     *  Execute the linked program if so requested and if there were no errors.
  261.     */
  262.  
  263. #if MACINTOSH
  264. #if MPW
  265.    /* Set file type to TEXT so it will be executable as a script. */
  266.    setfile(ofile,'TEXT','icon');
  267. #endif                    /* MPW */
  268. #endif                    /* MACINTOSH */
  269.  
  270.    rmfiles(rfiles);            /* remove intermediate files */
  271.    if (errors > 0) {            /* exit if linker errors seen */
  272.       unlink(ofile);
  273.       exit(ErrorExit);
  274.       }
  275.  
  276.    if (optind < argc)  {
  277.       if (!silent)
  278.          report("Executing");
  279.       execute (ofile, efile, argv+optind+1);
  280.       }
  281.  
  282.    exit(NormalExit);
  283.    }
  284.  
  285. /*
  286.  * execute - execute iconx to run the icon program
  287.  */
  288. static novalue execute(ofile,efile,args)
  289. char *ofile, *efile, **args;
  290.    {
  291.    int n;
  292.    char **argv, **p;
  293.  
  294.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  295.       ;
  296.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  297.  
  298.    *p++ = Iconx;            /* set iconx pathname